home *** CD-ROM | disk | FTP | other *** search
- /* init.c */
-
- /* Copyright © 1989 by Donald T. Meyer, Stormgate Software
- * All Rights Reserved
- */
-
-
-
- #include "rxil.h"
-
- #include <exec/memory.h>
-
- #include <string.h>
-
-
-
- static void unique_name( char portname[] );
-
- struct RxsLib *RexxSysBase = NULL;
-
- static char library_version_string[] = RXIL_VERSION_STRING;
-
-
-
- /* NAME
- * RxilInit
- *
- * SYNOPSIS
- * rdef = RxilInit( flags, portname );
- *
- * struct RxilDef *rdef;
- *
- * ULONG flags;
- * char *portname;
- *
- * FUNCTION
- * Open the ARexx library and setup our message ports. Then
- * allocate a RxilDef structure and do some default initialization
- * of it.
- * The portname will have a unique "instance" number appended
- * to it in the format "<name>_#<n>" where <name> is the string as
- * specified in the portname argument, and <n> is a decimal number
- * from 1-99 inclusive. This feature may be inhibited by setting
- * the RXIL_AS_IS flag.
- *
- * Even though this may fail, that should probably not be fatal
- * since the ARexx functionality is optional. The RxilCheckPort()
- * function is smart enough to just return if the rexx initialization
- * was not successsfull. Not to mention that RxilCheckPort() should
- * never get called since the rexx_sig_bit mask should be zero.
- *
- * INPUTS
- * flags These are various defined constants which control
- * which ports get opened and other various aspects
- * of port initialization.
- *
- * portname This is the name to use for the public ARexx port
- * that commands will be received at. It is suggested
- * that this be in uppercase and contain no spaces.
- * Maximum length is 40 characters, as set by the
- * defined constant RXIL_MAX_PORTNAME_LEN.
- * See discussion above about instance numbers.
- *
- * RESULT
- * A pointer to a RxilDef structure. Return is NULL for failure
- * to initialize the ARexx ports.
- *
- * SIDES
- *
- * HISTORY
- * 01-Aug-89 Creation.
- * 23-Sep-89 Changed "flags" arg from int to ULONG
- * 26-Sep-89 Sets the (new) version string pointer.
- * 01-Oct-89 Changed PublicPort name storage from a pointer to
- * a character array. Added "instance" numbering.
- * Added check on portname length.
- *
- * BUGS
- * This should probably share one signal bit between both ports
- * to avoid "hogging" signal bits.
- *
- * SEE ALSO
- * RxilCleanup(), RXIL_AS_IS, RXIL_MAX_PORTNAME_LEN
- */
-
- struct RxilDef *RxilInit( ULONG flags, char *portname )
- {
- char buf[24];
- struct RxilDef *rdef;
-
-
- if( ( strlen(portname) < 1 ) ||
- ( strlen(portname) > RXIL_MAX_PORTNAME_LEN ) )
- {
- /* Portname is of an invalid length */
- return( NULL );
- }
-
-
- rdef = AllocMem( sizeof(struct RxilDef), MEMF_PUBLIC | MEMF_CLEAR );
- if( rdef == NULL )
- {
- return( NULL );
- }
-
-
- /* Default initialization of the new RxilDef structure */
-
- rdef->Console = NULL;
- rdef->Extension = "rexx";
- rdef->HostPort = "REXX";
-
-
- strcpy( rdef->PortName, portname );
- if( FlagIsClear( flags, RXIL_AS_IS ) )
- {
- /* Make sure the public port name is unique */
- unique_name( rdef->PortName );
- }
-
- /* Open Rexx library */
- RexxSysBase = (struct RxsLib *)OpenLibrary( RXSNAME, 0L );
- if( RexxSysBase == NULL )
- {
- FreeMem( rdef, sizeof(struct RxilDef) );
- return( NULL );
- }
-
-
- if( FlagIsSet( flags, RXIL_PUBLIC ) )
- {
- /* Setup our public port */
-
- rdef->PublicPort = CreatePort( rdef->PortName, 1L );
- if( rdef->PublicPort == NULL )
- {
- CloseLibrary( (struct Library *)RexxSysBase );
- RexxSysBase = NULL;
- FreeMem( rdef, sizeof(struct RxilDef) );
- return( NULL );
- }
-
- rdef->SigBit |= 1L << (rdef->PublicPort->mp_SigBit);
- }
-
-
- if( FlagIsSet( flags, RXIL_SECRET ) )
- {
- /* Setup our secret port */
- strcpy( rdef->SecretPortName, rdef->PortName );
- strcat( rdef->SecretPortName, "_PRIVATE_" );
- stcul_d( buf, (long)FindTask(NULL) );
- strcat( rdef->SecretPortName, buf );
-
- rdef->SecretPort = CreatePort( rdef->SecretPortName, 1L );
- if( rdef->SecretPort == NULL )
- {
- /* Failure */
- if( rdef->PublicPort )
- {
- RxilDeletePort( rdef->PublicPort );
- rdef->PublicPort = NULL;
- }
-
- CloseLibrary( (struct Library *)RexxSysBase );
- RexxSysBase = NULL;
-
- rdef->SigBit = 0;
-
- FreeMem( rdef, sizeof(struct RxilDef) );
-
- return( NULL );
- }
-
- rdef->SigBit |= 1L << (rdef->SecretPort->mp_SigBit);
- }
-
-
- /* Set the version string pointer. */
- rdef->Version = &library_version_string[0];
-
-
- return( rdef );
- }
-
-
-
- /*
- * This will take the port name in the buffer, and add a sequential
- * invocation number to it to insure uniqueness.
- *
- * Note that this will increase the length of the given string!
- * Make sure that the buffer is at least 4 characters longer than
- * the original string.
- */
-
- static void unique_name( char portname[] )
- {
- char buf[RXIL_MAX_PORTNAME_LEN+10], buf2[4];
- unsigned int i;
-
-
- for( i=1; i<100; i++ )
- {
- strcpy( buf, portname ); /* Orig. name "APP" (example) */
- strcat( buf, "_#" ); /* "APP_#" */
- stcu_d( buf2, i );
- strcat( buf, buf2 ); /* "APP_#1" */
-
- if( FindPort( buf ) == NULL )
- {
- /* Okay, this name does not exist. Let's use it. */
- strcpy( portname, buf );
- return;
- }
- }
-
-
- /* Amazing! If we actually get here, there are already 99 instances
- * of this program running. I cannot imagine ever getting here. :-)
- * If we do, then I guess we'll just collide...
- */
- }
-
-